<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<title>Marvin JS Examples - Highlight By Unique ID</title>
	<link type="text/css" rel="stylesheet" href="../css/doc.css">
	<link type="text/css" rel="stylesheet" href="../js/lib/rainbow/github.css" />
	<script src="../js/lib/rainbow/rainbow-custom.min.js"></script>
	<script src="../js/lib/jquery-1.9.1.min.js"></script>
	<script src="../gui/lib/promise-1.0.0.min.js"></script>
	<script src="../js/marvinjslauncher.js"></script>
	<script type="text/javascript">
	var marvinSketcherInstance;
	var highlights = [];
	var parser = new DOMParser();
	
	$(document).ready(function handleDocumentReady (e) {
		MarvinJSUtil.getEditor("#sketch").then(function (sketcherInstance) {
			// initalize sketcher
			marvinSketcherInstance = sketcherInstance;
			$('#overwriteButton').click(onButtonClick);
			$('#appendButton').click(onButtonClick);
		});
	});
	
	
	function onButtonClick(e) {
		var b = (e.target.id =='overwriteButton');
		var selection = marvinSketcherInstance.getSelection();
		marvinSketcherInstance.exportStructure('mrv', { hasUID: true}).then(function(source) {
			if(b) {
				highlights = [];
			}
			highlights.push(createHighlight(source, selection));
			marvinSketcherInstance.setHighlight(highlights);
		}, alert);
	}
	
	function createHighlight(source, selection) {
		var xml = parser.parseFromString(source, "text/xml");
		var highlight = {};
		highlight.uids = {};
		highlight.uids.atoms = [];
		highlight.uids.bonds = [];
		var atoms = (selection.atoms.length == 0)? [] : selection.atoms.split(',');
		var bonds = (selection.bonds.length == 0)? [] : selection.bonds.split(',');
		for(i = 0; i < atoms.length; i++) {
			var atom = selectById(xml, 'a'+atoms[i]+'.prop1'); 
			if(atom) {
				var uid = atom.textContent;
				highlight.uids.atoms.push(uid);
			} else {
				console.log('Cannot find property#a'+atoms[i]+'.prop1');
			}
		}
		for(i = 0; i < bonds.length; i++) {
			var edges = bonds[i].split('-');
			var bond = selectById(xml, 'a'+edges[0]+'a'+edges[1]+'.prop1');
			if(bond) {
				var buid = bond.textContent;
				highlight.uids.bonds.push(buid);
			} else {
				console.log('Cannot find property#a'+edges[0]+'a'+edges[1]+'.prop1');
			}
		}
		highlight.style = {}
		highlight.style.color = $('#colorValue').val();
		var opacity = $('#opacityValue').val()/100;
		highlight.style.opacity = opacity;
		var size = $('#sizeValue').val()/100;
		highlight.style.size = size;
		return highlight;
	}
	
	function getId() {
		xml.getElementsByTagName("scalar");
	}
	
	(function(win, xmlParser) {
		if(!win.selectById) {
			var _xml = xmlParser.parseFromString("<xml><foo id=\"foo\"/></xml>", "text/xml");
			if(_xml.getElementById('foo')) {
				win.selectById = function(doc, id) {
					return doc.getElementById(id);
				}
			} else {
				win.selectById = function(doc, id) {
					return doc.querySelector('[id="'+id+'"]');
				} 
			} 
		}
	}(window, parser));
	</script>
</head>
<body>
	<h1>Marvin JS Examples - Highlight By Unique ID</h1>
	<div style="clear: both; width: 100%; text-align: right;"><a href="index.html">Back to index</a></div>
	<div class="resizable">
		<iframe src="../editor.html?uid" id="sketch" class="sketcher-frame" data-reaction="off"></iframe>
	</div>
	<div>
		Color: <input type="color" id="colorValue" value="#FF7F50"/>
		Opacity (0-100%): <input type="number" min="10" max="100" step="10" id="opacityValue" value="30"></input>
		Size (40-200%): <input type="number" min="40" max="200" step="10" id="sizeValue" value="100"></input>
		<input type="button" id="overwriteButton" value="Overwrite highlight"/>
		<input type="button" id="appendButton" value="Append highlight"/>
	</div>
	<p>This example demonstrates how to paint a custom patch for atoms and bonds.</p>
	<p>How to try it:</p>
	<p>Draw a structure and select those atoms and bonds that you would like to highlight with colored patch.</p>
	<p>After that, specify the style: select color, setup opacity value between 0.0 and 1.0 (0 is full transparent, 1 is total opaque). 
	Then, set the relative size of the patch (relative to the selection feedback). Finally, apply settings. </p>
	<p>If you push <strong>Overwrite highlight</strong> button, the previously set patches will be deleted. 
	If you choose <strong>Append highlight</strong>, the current patches will be preserved and new settings will be appended to them.</p>
	<p>Notes:
	<ul>
		<li>If several styles are applied to the editor, the patches may overlaps each other.</li>
		<li>Reaction converter is switched off to avoid atom index collision (among reaction compounds).</li>
	</ul>
	</p>
	
	<p>You can see the code comment below.</p>
	<p>First of all, we request a reference to the loaded editor. Then, we bind click handler for the submit buttons. 
	We will need an array (highlights)were we cache the applied styles and a DOM parser (parser) that helps us to seek data in MRV sources.</p>
	<pre><code data-language="javascript">	var marvinSketcherInstance;
	var highlights = [];
	var parser = new DOMParser();
	
	$(document).ready(function handleDocumentReady (e) {
		MarvinJSUtil.getEditor("#sketch").then(function (sketcherInstance) {
			// initalize sketcher
			marvinSketcherInstance = sketcherInstance;
			$('#overwriteButton').click(onButtonClick);
			$('#appendButton').click(onButtonClick);
		});
	});</code></pre>
	
	<p>The <code>onButtonClick</code> function, determines the current behavior: append or overwrite the current style with the new one. 
	After that, we retrieve the selection from the editor to apply the new style to the desired atoms/bonds. 
	In the selection, the atoms and bonds are referred by atom indexes.</p>
	<p>To retrieve the unique ID (UID) of these atoms, we have to get the molecule source of the structure.
	To do that, specify <code>hasUID</code> export option in <code>exportStructure</code> function.</p>
	<p>When the molecule source arrived, we are ready to create the new highlight settings.</p>
	<p>If we choose the overwrite option, we reset the previously stored highlight history (<code>highlights</code>).</p>
	<p>The <code>createHighlight</code> function is responsible to create the new highlight style from the given data.
	The new highlight object is added to the <code>highlights</code> array.
	This array is applied to the <code>setHighlight</code> function of the editor.</p> 
	<pre><code data-language="javascript">	function onButtonClick(e) {
		var b = (e.target.id =='overwriteButton');
		var selection = marvinSketcherInstance.getSelection();
		marvinSketcherInstance.exportStructure('mrv', { hasUID: true}).then(function(source) {
			if(b) {
				highlights = [];
			}
			highlights.push(createHighlight(source, selection));
			marvinSketcherInstance.setHighlight(highlights);
		}, alert);
	}</code></pre>
	<p>The <code>createHighlight</code> function expects two parameters: the molecule source and the selection object.
	First of all, an xml object is created from the MRV source to be able to seek the UID properties.
	Atom UID is stored in a child (<code>scalar</code>) tag of the atom tag.
	The <code>atoms</code> field of the <code>selection</code> object gives index of selected atoms.
	The ID of the scalar tag that describes the UID property of the n-th atom can describe in the following format:
	<code>a<strong>&lt;index&gt;</strong>.prop1</code> where <code><strong>&lt;index&gt;</strong></code> is the index of the atom. 
	Get it with the help of the <code>getElementById</code> function, and appends its value to the <code>highlight.uids.atoms</code> array.</p>
	<p>You can get bond UID in a similar way. In this case, the ID of the scalar tag is in the following format:
	<code>a<strong></strong>&lt;index of begin atom&gt</strong>;a<strong></strong>&lt;index of end atom&gt;</strong>.prop1</code>. 
	The bond UIDs are collected into <code>highlight.uids.bond</code> array.</p>
	<p>After that, you can create the <code>highlight.style</code> object. Retrieve the value of the color input field.
	Convert value of the <code>opacity</code> field into the 0 - 1 range. Do the same with the <code>size</code> value.</p>
	<p>The created highlight objects define atoms and bonds by UID and specify style with color, opacity and size properties.</p>
	<pre><code data-language="javascript">	function createHighlight(source, selection) {
		var xml = parser.parseFromString(source, "text/xml");
		var highlight = {};
		highlight.uids = {};
		highlight.uids.atoms = [];
		highlight.uids.bonds = [];
		var atoms = (selection.atoms.length == 0)? [] : selection.atoms.split(',');
		var bonds = (selection.bonds.length == 0)? [] : selection.bonds.split(',');
		for(i = 0; i < atoms.length; i++) {
			var atom = selectById(xml, 'a'+atoms[i]+'.prop1'); 
			if(atom) {
				var uid = atom.textContent;
				highlight.uids.atoms.push(uid);
			} else {
				console.log('Cannot find property#a'+atoms[i]+'.prop1');
			}
		}
		for(i = 0; i < bonds.length; i++) {
			var edges = bonds[i].split('-');
			var bond = selectById(xml, 'a'+edges[0]+'a'+edges[1]+'.prop1');
			if(bond) {
				var buid = bond.textContent;
				highlight.uids.bonds.push(buid);
			} else {
				console.log('Cannot find property#a'+edges[0]+'a'+edges[1]+'.prop1');
			}
		}
		highlight.style = {}
		highlight.style.color = $('#colorValue').val();
		var opacity = $('#opacityValue').val()/100;
		highlight.style.opacity = opacity;
		var size = $('#sizeValue').val()/100;
		highlight.style.size = size;
		return highlight;
	}</code></pre>
	<div style="clear: both; width: 100%; text-align: right;"><a href="index.html">Back to index</a></div>
  </body>
</html>
